#pragma semicolon 1
#pragma newdecls required
#include <sourcemod>
#include <sdktools>

#define PLUGIN_NAME                   "l4d2_speed_of_light_charger"    //这里写插件名字
#define PLUGIN_AUTHOR                 "豆瓣酱な"                         //作者
#define PLUGIN_DESCRIPTION            "光速牛"   //介绍
#define PLUGIN_VERSION                "1.0"
#define PLUGIN_URL                    "https://gitee.com/sweet-and-sour-bombs"  //网站

//原贴地址
//https://forums.alliedmods.net/showthread.php?p=2092125#post2092125


public Plugin myinfo =
{
    name        = PLUGIN_NAME,
    author      = PLUGIN_AUTHOR,
    description = PLUGIN_DESCRIPTION,
    version     = PLUGIN_VERSION,
    url         = PLUGIN_URL
}

Handle PluginStartTimer = INVALID_HANDLE;

bool isLocomotive = false;

Handle	cvarLocomotive;
Handle	cvarLocomotiveSpeed;
Handle	cvarLocomotiveDuration;

bool isCharging[MAXPLAYERS+1] = { false };
static int laggedMovementOffset = false;

#define ZOMBIECLASS_CHARGER 						6

public void OnPluginStart()
{

	cvarLocomotive = CreateConVar("l4d_ucm_locomotive", "1.0", "机车：在冲锋时，Cherger 能够增加速度和持续时间，它不会击中任何东西的时间越长. (Def 1)", FCVAR_NOTIFY);
	
	
	cvarLocomotiveSpeed = CreateConVar("l4d_ucm_locomotivespeed", "20.0", "乘以倍数 Cherger 的增加速度. (Def 1.4)", FCVAR_NOTIFY);
	
	
	cvarLocomotiveDuration = CreateConVar("l4d_ucm_locomotiveduration", "4.0", "时间的 Cherger 继续运行. (Def 4.0)", FCVAR_NOTIFY);


	HookEvent("charger_charge_start", Event_ChargeStart); //Charger 冲锋开始事件
	HookEvent("charger_charge_end", Event_ChargeEnd); //Charger 冲锋结束事件
	PluginStartTimer = CreateTimer(3.0, OnPluginStart_Delayed);
	
	//AutoExecConfig(true, "l4d2_speed_of_light_charger");	
	
}


//Charger 冲锋开始事件
void Event_ChargeStart(Event event, const char[] name, bool dontBroadcast)  
{

	int client = GetClientOfUserId(GetEventInt(event, "userid"));


	// =====================================
	// Charger Ability: Locomotive
	// =====================================
	if (isLocomotive)
	{
		ChargerAbility_LocomotiveStart(client);
	}
	
	if (IsValidClient(client))
	{
		isCharging[client] = true;
	}
}


//Charger 冲锋结束事件
void Event_ChargeEnd(Event event, const char[] name, bool dontBroadcast) 
{
	int client = GetClientOfUserId(GetEventInt(event, "userid"));	
	
	// =====================================
	// Charger Ability: Locomotive
	// =====================================
	if (isLocomotive)
	{
		ChargerAbility_LocomotiveFinish(client);
	}
		
	if (IsValidClient(client))
	{
		isCharging[client] = false;
	}
}

public Action OnPluginStart_Delayed(Handle timer)
{	

	
	if (GetConVarInt(cvarLocomotive))
	{
		isLocomotive = true;
		float duration = GetConVarFloat(cvarLocomotiveDuration);		
		SetConVarFloat(FindConVar("z_charge_duration"), duration, false, false);
	}
	laggedMovementOffset = FindSendPropInfo("CTerrorPlayer", "m_flLaggedMovementValue");
	
	if(PluginStartTimer != INVALID_HANDLE)
	{
 		KillTimer(PluginStartTimer);
		PluginStartTimer = INVALID_HANDLE;
	}				
	
	return Plugin_Stop;
}


// ===========================================
// Charger Ability: Locomotive
// ===========================================
// Description: While charging, the Charger is able to increase speed and duration the longer it doesn't hit anything.


void ChargerAbility_LocomotiveStart(any client)
{
	if (IsValidCharger(client))
	{
		SetEntDataFloat(client, laggedMovementOffset, 1.0*GetConVarFloat(cvarLocomotiveSpeed), true);
	}
}


void ChargerAbility_LocomotiveFinish(any client)
{
	if (IsValidCharger(client))
	{
		SetEntDataFloat(client, laggedMovementOffset, 1.0, true);
	}
}

bool IsValidClient(int client)
{
	if (client <= 0)
		return false;
		
	if (client > MaxClients)
		return false;
		
	if (!IsClientInGame(client))
		return false;
		
	if (!IsPlayerAlive(client))
		return false;

	return true;
}


bool IsValidCharger(int client)
{
	if (IsValidClient(client) && GetClientTeam(client) == 3)
	{
		int class = GetEntProp(client, Prop_Send, "m_zombieClass");
		
		if (class == ZOMBIECLASS_CHARGER)
			return true;
		
		return false;
	}
	
	return false;
}













